package vip.specimen.system.common.implement;

import com.aliyun.oss.ClientBuilderConfiguration;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.*;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import vip.specimen.system.common.connector.SaveMethodInterface;
import vip.specimen.system.common.enums.ResultCode;
import vip.specimen.system.common.enums.SaveMethodEnum;
import vip.specimen.system.common.handler.SystemExceptionHandler;
import vip.specimen.system.datasource.entity.SystemResourceEntity;
import vip.specimen.system.datasource.entity.SystemResourceSuffixEntity;
import vip.specimen.system.datasource.entity.SystemSaveConfigEntity;
import vip.specimen.system.result.JsonResult;
import vip.specimen.system.service.SystemResourceService;
import vip.specimen.system.service.SystemResourceSuffixService;
import vip.specimen.system.service.SystemSaveConfigService;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;
import java.util.UUID;

/**
 * *@Author: 余浪人
 * *@Date：2021/04/17 20:15
 * *@Email:yulangren520@Gmail.com
 * *@QQ:1368419640
 **/
@Getter
@Setter
@Slf4j
@Component
public class AliOssUpload implements SaveMethodInterface {
    private String endpoint = "";
    private String accessKeyId = "";
    private String accessKeySecret = "";
    private String bucketName = "<yourBucketName>";
    private String domain;
    private OSS ossClient;
    @Resource
    private SystemSaveConfigService saveConfigService;
    @Resource
    private SystemResourceService resourceService;
    @Resource
    private SystemResourceSuffixService resourceSuffixService;
    public static AliOssUpload aliOssUpload;

    @Override
    @PostConstruct
    public void init() {
        aliOssUpload = this;
        aliOssUpload.resourceSuffixService = resourceSuffixService;
        aliOssUpload.resourceService = resourceService;
        aliOssUpload.saveConfigService = saveConfigService;
        SystemSaveConfigEntity configEntity = aliOssUpload.saveConfigService.getConfig();
        aliOssUpload.endpoint = configEntity.getAliEndpoint();
        aliOssUpload.accessKeyId = configEntity.getAliAccessKey();
        aliOssUpload.accessKeySecret = configEntity.getAliAccessKeySecret();
        aliOssUpload.domain = configEntity.getAliEndpoint();
        ClientBuilderConfiguration conf = new ClientBuilderConfiguration();
        conf.setSupportCname(configEntity.isAliSupportCname());
        aliOssUpload.ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret, conf);
    }

    @Override
    public JsonResult<SystemResourceEntity> upload(MultipartFile file) {
        String originalName = file.getOriginalFilename();
        String uuid = UUID.randomUUID().toString().substring(0, 8);
        String suffix = originalName.substring(originalName.indexOf(".")).toLowerCase();
        SystemResourceSuffixEntity suffixEntity = aliOssUpload.resourceSuffixService.findBySuffix(suffix);
        if (null == suffixEntity || !suffixEntity.isEnable() || null == suffixEntity.getKindEntity() || !suffixEntity.getKindEntity().isEnable()) {
            throw new SystemExceptionHandler(ResultCode.ERROR_UPLOAD_NOT_ALLOW);
        }
        String path = suffixEntity.getKindEntity().getPath().startsWith("/") ? suffixEntity.getKindEntity().getPath().substring(1) : suffixEntity.getKindEntity().getPath();
        String name = uuid + suffix;
        String fileName = !path.endsWith("/") ? path + "/" + name : path + name;
        try {
            PutObjectResult result = aliOssUpload.ossClient.putObject(new PutObjectRequest(aliOssUpload.bucketName, fileName, file.getInputStream()));
            System.err.println(result);
            closeOss();
        } catch (IOException e) {
            e.printStackTrace();
        }
        String resourceUrl = aliOssUpload.domain + "/" + fileName;
        SystemResourceEntity resource = aliOssUpload.resourceService.insert(new SystemResourceEntity(name, file.getSize(), originalName, resourceUrl, file.getContentType(), suffixEntity, SaveMethodEnum.ALiYun, fileName));
        return JsonResult.success(resource);
    }

    @Override
    public void download(String fileName) throws IOException {
        // ossObject包含文件所在的存储空间名称、文件名称、文件元信息以及一个输入流。
        OSSObject ossObject = aliOssUpload.ossClient.getObject(aliOssUpload.bucketName, fileName);
        // 读取文件内容。
        System.out.println("Object content:");
        BufferedReader reader = new BufferedReader(new InputStreamReader(ossObject.getObjectContent()));
        while (true) {
            String line = reader.readLine();
            if (line == null) break;
            System.out.println("\n" + line);
        }
        // 数据读取完成后，获取的流必须关闭，否则会造成连接泄漏，导致请求无连接可用，程序无法正常工作。
        reader.close();
        closeOss();
    }

    @Override
    public boolean delete(String key) {
        try {
            aliOssUpload.ossClient.deleteObject(aliOssUpload.bucketName, key);
            closeOss();
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    @Override
    public List getFileList() {
        ListObjectsV2Result result = aliOssUpload.ossClient.listObjectsV2(aliOssUpload.bucketName);
        List<OSSObjectSummary> ossObjectSummaries = result.getObjectSummaries();
        for (OSSObjectSummary s : ossObjectSummaries) {
            System.out.println("\t" + s.getKey());
        }
        return null;
    }


    private void closeOss() {
        aliOssUpload.ossClient.shutdown();
    }
}
